/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package view.inventory;

import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.*;
import main.ServicesList;
import model.inventory.Dept;
import model.inventory.Item;
import model.inventory.Packaging;
import model.inventory.Principal;
import model.inventory.Unit;
import org.apache.log4j.Logger;
import utility.Constants;
import utility.NameValueList;
import utility.StringUtils;
import utility.com.ComponentUtils;
import utility.com.InputValidation;
import utility.com.TextComponentUtils;
import utility.typeSafe.EnumUtils;
import utility.typeSafe.ItemPerfoma;
import view.lookup.LookupDeptFrm;
import view.lookup.LookupSimpleFrm;

/**
 *
 * @author jay
 */
public class ItemFrm extends javax.swing.JDialog {

    private Item item;
    private Object oldValue, newValue;
    private List<NameValueList> performList = EnumUtils.enumToNameValueList(ItemPerfoma.class);
    private static Logger log = Logger.getLogger(ItemFrm.class);
    
    public ItemFrm() {
        super(ServicesList.MAIN_FRAME, true);
        initComponents();
        initComponentsRules();
    }

    public int execute(int id) {
        setLocationRelativeTo(null);
        initForm();
        if (id!=0) { loadData(id); }

        setVisible(true);
        if (item!=null) {
        return item.getId();}
        else { return 0; }
    }

    public void initButtonState(boolean status){
        btnSave.setEnabled(status);
    }
    
    public void initForm(){
        item = new Item();
        
        txtNama.setText("");
        txtKode.setText("");
        txtKemasan.setText("");
        txtBar1.setText("");
        txtBar2.setText("");
        txtDept.setText("");
        txtDiv.setText("");
        txtPrincipal.setText("");
        txtSatuan.setText("");
        txtStokMax.setText("0");
        txtStokMin.setText("0");
        txtStokX.setText("0");
        txtStruk.setText("");
        chkBKP.setSelected(true);
        chkConsi.setSelected(false);
        chkHalal.setSelected(true);
        cmbPerform.setSelectedIndex(0);
    }
    
    public void loadData(int id){
        item = ServicesList.getItemService().getItem(id);
        if (item != null) {
            txtBar1.setText(item.getBarcode());
            txtBar2.setText(item.getBarcode2());
            txtKode.setText(item.getPlu());
            txtNama.setText(item.getNama());
            
            if (item.getStokMax() != null) {txtStokMax.setText(item.getStokMax().toString()); }
            if (item.getStokMax() != null) {txtStokMin.setText(item.getStokMin().toString()); }
            if (item.getStokMax() != null) {txtStokX.setText(item.getStokX().toString()); }
            if (item.getStokMax() != null) {txtStruk.setText(item.getStruk()); }
            if (item.getStokMax() != null) {chkBKP.setSelected(item.getBkp()); }
            if (item.getStokMax() != null) {chkConsi.setSelected(item.getKonsinyasi()); }
            if (item.getStokMax() != null) {chkHalal.setSelected(item.getHalal()); }
            if (item.getStokMax() != null) {txtDiv.setText(item.getDivOrder()); }
           
            if (item.getDept() != null) { txtDept.setText(item.getDept().getNama()); }
            if (item.getPackaging() != null) { txtKemasan.setText(item.getPackaging().getNama()); }
            if (item.getPrincipal() != null) { txtPrincipal.setText(item.getPrincipal().getNama()); }
            if (item.getUnit() != null) { txtSatuan.setText(item.getUnit().getNama()); }
            cmbPerform.setSelectedIndex(NameValueList.indexOf(performList, item.getPerforma()));
        }
    }
    
    public void saveData(){
        
        if (item.getDept()==null) {item.setDept(ServicesList.getDeptService().getDept(Constants.MASTER_ITEM_DEPTEMENT));}
        item.setBarcode(txtBar1.getText());
        item.setBarcode2(txtBar2.getText());
        item.setBkp(chkBKP.isSelected());
        if (txtDiv.getText()==null) { txtDiv.setText(""); }
        item.setDivOrder(txtDiv.getText()); 
        
        item.setHalal(chkHalal.isSelected());
        item.setKonsinyasi(chkConsi.isSelected());
        item.setNama(txtNama.getText());
        item.setPerforma(((NameValueList) cmbPerform.getSelectedItem()).getKey());
        item.setPlu(txtKode.getText());
        
        if (txtStokMax.getText()==null) { txtStokMax.setText("0"); }
        item.setStokMax(Integer.parseInt(txtStokMax.getText()));
        
        if (txtStokMin.getText()==null) { txtStokMin.setText(""); }
        item.setStokMin(Integer.parseInt(txtStokMin.getText()));
        
        if (txtStokX.getText()==null) { txtStokX.setText(""); }
        item.setStokX(Integer.parseInt(txtStokX.getText()));
        
        if (txtStruk.getText()==null || "".equals(txtStruk.getText())) { txtStruk.setText(txtNama.getText()); }
        item.setStruk(txtStruk.getText());
       
     
        boolean saved = false;
        try{
            saved = ServicesList.getItemService().save(item);
            
        } catch(Exception ex){
            log.error(ex);
            JOptionPane.showMessageDialog(this, "Data gagal disimpan."
            ,"Error",JOptionPane.ERROR_MESSAGE);
        }
        
        initButtonState(!saved);
    }
    
    public void validasi(){
        if (item.getPerforma()==null) {
            cmbPerform.setSelectedIndex(NameValueList.indexOf(performList, ItemPerfoma.DEFAULT.toString()));
        }
        if (txtKode.getText()==null) {txtKode.setText("");}
        if (txtBar1.getText()==null) {txtBar1.setText("");}
        if (txtBar2.getText()==null) {txtBar2.setText("");}
        if (txtNama.getText()==null) {txtNama.setText("");}
        
        Map<NameValueList, Object> params = new HashMap<>();
        params.put(new NameValueList(null, Constants.OPERATOR_CUSTOM), 
            "(item.id <> "+item.getId()+") "+
            " and ((item.plu = "+StringUtils.fmtSQLString(txtKode.getText())+")"+
            (!txtBar1.getText().equals("") ? " or (item.barcode = "+StringUtils.fmtSQLString(txtBar1.getText())+")" :"")+
            (!txtBar2.getText().equals("") ? " or (item.barcode2 = "+StringUtils.fmtSQLString(txtBar2.getText())+")" :"")+")"
        );
        
        if (InputValidation.isValid(txtKode, !"".equals(txtKode.getText()), "PLU belum diisi.")) {
        if (InputValidation.isValid(txtNama, !"".equals(txtNama.getText()), "Nama belum diisi.")) {
        if (InputValidation.isValid(txtDept, item.getDept()!=null, "Kategori belum diisi.")) {
        if (InputValidation.isValid(txtDept, item.getDept()!=null, "Kategori belum diisi.")) {
            Boolean notExist = !ServicesList.getItemService().isExist(params); 
            if (InputValidation.isValid(txtKode, notExist, "Kode/Barcode sudah ada.")) {
                saveData();
            }
        }}}}
    }
    
    private void lookupMaster(int purpose, String param) {
        Object object;
        if (purpose==Constants.LOOKUP_DEPT) {
            object = new LookupDeptFrm().execute();
        } else {
            object = new LookupSimpleFrm().execute(purpose, param);
        }
                
        if (object != null) {
            setMaster(purpose, object);
        }
    }
    
    private void setMaster(int purpose, Object object) {
         if (object != null) {
            switch (purpose) {
                case Constants.LOOKUP_DEPT:
                    item.setDept((Dept) object);
                    txtDept.setText(item.getDept().getNama());
                    txtPrincipal.requestFocus();
                    break;
                    
                case Constants.LOOKUP_PACKAGE:
                    item.setPackaging((Packaging) object);
                    txtKemasan.setText(item.getPackaging().getNama());
                    txtNama.requestFocus();
                    break;
                    
                case Constants.LOOKUP_PRINCIPAL:
                    item.setPrincipal((Principal) object);
                    txtPrincipal.setText(item.getPrincipal().getNama());
                    txtKemasan.requestFocus();
                    break;
                    
                case Constants.LOOKUP_UNIT:
                    item.setUnit((Unit) object);
                    txtSatuan.setText(item.getUnit().getNama());
                    txtStokMin.requestFocus();
                    break;
                default: break;    
            }
        }
    }
    
    private void getMaster(int purpose, String kode) {
        switch (purpose) {
           case Constants.LOOKUP_DEPT:
               item.setDept(ServicesList.getDeptService().getDept(kode));
               if (item.getDept() != null) {
                   setMaster(purpose, item.getDept());
               }else { lookupMaster(purpose, txtDept.getText()); }
               break;
               
           case Constants.LOOKUP_PACKAGE:
               item.setPackaging(ServicesList.getPackagingService().getPackaging(kode));
               if (item.getPackaging() != null) {
                   setMaster(purpose, item.getPackaging());
               }else { lookupMaster(purpose, txtKemasan.getText()); }
               break;
               
           case Constants.LOOKUP_PRINCIPAL:
               item.setPrincipal(ServicesList.getPrincipalService().getPrincipal(kode));
               if (item.getPrincipal() != null) {
                   setMaster(purpose, item.getPrincipal());
               }else { lookupMaster(purpose, txtPrincipal.getText()); }
               break;
               
           case Constants.LOOKUP_UNIT:
               item.setUnit(ServicesList.getUnitService().getUnit(kode));
               if (item.getUnit() != null) {
                   setMaster(purpose, item.getUnit());
               }else { lookupMaster(purpose, txtSatuan.getText()); }
               break;
               
           default: break;    
        }
    }
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        txtKode = new javax.swing.JTextField();
        txtBar1 = new javax.swing.JTextField();
        txtBar2 = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        txtDept = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        txtPrincipal = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        txtKemasan = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        txtNama = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        txtStruk = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        cmbPerform = new javax.swing.JComboBox();
        txtDiv = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        txtSatuan = new javax.swing.JTextField();
        jLabel9 = new javax.swing.JLabel();
        txtStokMin = new javax.swing.JTextField();
        jLabel10 = new javax.swing.JLabel();
        txtStokMax = new javax.swing.JTextField();
        txtStokX = new javax.swing.JTextField();
        jLabel11 = new javax.swing.JLabel();
        chkHalal = new javax.swing.JCheckBox();
        chkConsi = new javax.swing.JCheckBox();
        chkBKP = new javax.swing.JCheckBox();
        jLabel12 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        btnAdd = new javax.swing.JButton();
        btnSave = new javax.swing.JButton();
        btnClose = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        txtKode.setText("jTextField1");
        txtKode.setName("txtKode"); // NOI18N

        txtBar1.setText("jTextField1");
        txtBar1.setName("txtBar1"); // NOI18N

        txtBar2.setText("888888888888888");
        txtBar2.setName("txtBar2"); // NOI18N

        jLabel1.setText("PLU :");

        jLabel2.setText("Barcode :");

        txtDept.setText("jTextField1");
        txtDept.setName("txtDept"); // NOI18N

        jLabel3.setText("Kategori :");

        txtPrincipal.setText("jTextField1");
        txtPrincipal.setName("txtPrincipal"); // NOI18N

        jLabel4.setText("Principal :");

        txtKemasan.setText("jTextField1");
        txtKemasan.setName("txtKemasan"); // NOI18N

        jLabel5.setText("Kemasan :");

        txtNama.setText("jTextField1");
        txtNama.setName("txtNama"); // NOI18N

        jLabel6.setText("Nama :");

        txtStruk.setText("jTextField1");
        txtStruk.setName("txtStruk"); // NOI18N

        jLabel7.setText("Nama Struk :");

        cmbPerform.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        cmbPerform.setName("cmbPerform"); // NOI18N

        txtDiv.setText("jTextField1");
        txtDiv.setName("txtDiv"); // NOI18N

        jLabel8.setText("Divisi PO :");

        txtSatuan.setText("jTextField1");
        txtSatuan.setName("txtSatuan"); // NOI18N

        jLabel9.setText("Satuan :");

        txtStokMin.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        txtStokMin.setText("jTextField1");
        txtStokMin.setName("txtStokMin"); // NOI18N

        jLabel10.setText("Stok Min :");

        txtStokMax.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        txtStokMax.setText("jTextField1");
        txtStokMax.setName("txtStokMax"); // NOI18N

        txtStokX.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        txtStokX.setText("jTextField1");
        txtStokX.setName("txtStokX"); // NOI18N
        txtStokX.setNextFocusableComponent(btnSave);

        jLabel11.setText("Stok Max :");

        chkHalal.setText("Halal");
        chkHalal.setName("chkHalal"); // NOI18N

        chkConsi.setText("Konsinyasi");
        chkConsi.setName("chkConsi"); // NOI18N

        chkBKP.setText("BKP");
        chkBKP.setName("chkBKP"); // NOI18N

        jLabel12.setText("Tag :");

        jLabel13.setText("Stok X :");

        btnAdd.setText("Tambah");
        btnAdd.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnAdd.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddActionPerformed(evt);
            }
        });

        btnSave.setText("Simpan");
        btnSave.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnSave.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });

        btnClose.setText("Close");
        btnClose.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnClose.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCloseActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(26, 26, 26)
                                .addComponent(jLabel2)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(txtBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(txtBar2, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addGap(47, 47, 47)
                                .addComponent(jLabel1)
                                .addGap(10, 10, 10)
                                .addComponent(txtKode, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(layout.createSequentialGroup()
                                        .addGap(22, 22, 22)
                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.TRAILING)
                                            .addComponent(jLabel4, javax.swing.GroupLayout.Alignment.TRAILING)
                                            .addComponent(jLabel5, javax.swing.GroupLayout.Alignment.TRAILING)
                                            .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.TRAILING)))
                                    .addGroup(layout.createSequentialGroup()
                                        .addContainerGap()
                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(jLabel7)
                                                        .addComponent(jLabel12, javax.swing.GroupLayout.Alignment.TRAILING))
                                                    .addComponent(jLabel9, javax.swing.GroupLayout.Alignment.TRAILING))
                                                .addComponent(jLabel10, javax.swing.GroupLayout.Alignment.TRAILING))
                                            .addComponent(jLabel11, javax.swing.GroupLayout.Alignment.TRAILING)))
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                        .addContainerGap()
                                        .addComponent(jLabel13)))
                                .addGap(19, 19, 19)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(txtDept, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(txtPrincipal, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(txtKemasan, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(txtNama, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(txtStruk, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(cmbPerform, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(29, 29, 29)
                                        .addComponent(jLabel8)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(txtDiv, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(txtSatuan, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(23, 23, 23)
                                        .addComponent(chkBKP))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(txtStokMin, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(23, 23, 23)
                                        .addComponent(chkHalal))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(txtStokMax, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(24, 24, 24)
                                        .addComponent(chkConsi))
                                    .addComponent(txtStokX, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE))))
                        .addGap(0, 2, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(btnAdd)
                        .addGap(1, 1, 1)
                        .addComponent(btnSave)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnClose)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtKode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(txtBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtBar2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtDept, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtPrincipal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtKemasan, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtNama, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtStruk, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(cmbPerform, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel12))
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(txtDiv, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel8)))
                .addGap(8, 8, 8)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(txtSatuan, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel9))
                    .addComponent(chkBKP))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(3, 3, 3)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(txtStokMin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel10)))
                    .addComponent(chkHalal))
                .addGap(3, 3, 3)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(chkConsi)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(3, 3, 3)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(txtStokMax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel11))))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtStokX, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel13))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnAdd)
                    .addComponent(btnSave)
                    .addComponent(btnClose))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddActionPerformed
        initForm();
        txtKode.requestFocus();
    }//GEN-LAST:event_btnAddActionPerformed

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        validasi();
    }//GEN-LAST:event_btnSaveActionPerformed

    private void btnCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCloseActionPerformed
        dispose();
    }//GEN-LAST:event_btnCloseActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAdd;
    private javax.swing.JButton btnClose;
    private javax.swing.JButton btnSave;
    private javax.swing.JCheckBox chkBKP;
    private javax.swing.JCheckBox chkConsi;
    private javax.swing.JCheckBox chkHalal;
    private javax.swing.JComboBox cmbPerform;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JTextField txtBar1;
    private javax.swing.JTextField txtBar2;
    private javax.swing.JTextField txtDept;
    private javax.swing.JTextField txtDiv;
    private javax.swing.JTextField txtKemasan;
    private javax.swing.JTextField txtKode;
    private javax.swing.JTextField txtNama;
    private javax.swing.JTextField txtPrincipal;
    private javax.swing.JTextField txtSatuan;
    private javax.swing.JTextField txtStokMax;
    private javax.swing.JTextField txtStokMin;
    private javax.swing.JTextField txtStokX;
    private javax.swing.JTextField txtStruk;
    // End of variables declaration//GEN-END:variables
    
    @Override
    public void setVisible(boolean value) {
        super.setVisible(value);
        txtKode.requestFocusInWindow();
    }
    
    public void moveNext() {
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.focusNextComponent();
    }
    
    class ActionKeyListener implements KeyListener {
        @Override public void keyTyped(KeyEvent e) {} 
        @Override public void keyReleased(KeyEvent e) {}
        
        @Override public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) { 
                case KeyEvent.VK_F2: 
                    switch(e.getComponent().getName()) {
                        case "txtDept": lookupMaster(Constants.LOOKUP_DEPT, txtDept.getText()); break;
                        case "txtPrincipal": lookupMaster(Constants.LOOKUP_PRINCIPAL, txtPrincipal.getText()); break;
                        case "txtKemasan": lookupMaster(Constants.LOOKUP_PACKAGE, txtKemasan.getText()); break;
                        case "txtSatuan": lookupMaster(Constants.LOOKUP_UNIT, txtSatuan.getText()); break;
                    };
                break;  
                
                case KeyEvent.VK_ENTER: 
                    switch(e.getComponent().getName()) {
                        case "txtDept": 
                            newValue = txtDept.getText();
                            if (!newValue.equals(oldValue)) { getMaster(Constants.LOOKUP_DEPT, txtDept.getText()); }
                            else {moveNext();}
                            break;
                            
                        case "txtPrincipal": 
                            newValue = txtPrincipal.getText();
                            if (!newValue.equals(oldValue)) { getMaster(Constants.LOOKUP_PRINCIPAL, txtPrincipal.getText()); }
                            else {moveNext();}
                            break;
                            
                        case "txtKemasan": 
                            newValue = txtKemasan.getText();
                            if (!newValue.equals(oldValue)) { getMaster(Constants.LOOKUP_PACKAGE, txtKemasan.getText()); }
                            else {moveNext();}
                            break;
                            
                        case "txtSatuan": 
                            newValue = txtDept.getText();
                            if (!newValue.equals(oldValue)) { getMaster(Constants.LOOKUP_UNIT, txtDept.getText()); }
                            else {moveNext();}
                            break;
                            
                       default: moveNext(); break;
                    };
                    
                break;      
            }
        }
    }
    
    class ActionFocusGained implements FocusListener {
        @Override public void focusGained(FocusEvent e) { 
            Component componen = (Component) e.getSource(); 
            if (componen instanceof JTextField) { oldValue = ((JTextField) componen).getText();
            }else if (componen instanceof JComboBox) { oldValue = ((JComboBox) componen).getSelectedIndex();
            }else if (componen instanceof JCheckBox) { oldValue = ((JCheckBox) componen).isSelected();
            }else if (componen instanceof JTextArea) { oldValue = ((JTextArea) componen).getText(); }
        }
        
        @Override public void focusLost(FocusEvent e) {
            Component componen = (Component) e.getSource(); 
            if (componen instanceof JTextField) { newValue = ((JTextField) componen).getText();
            }else if (componen instanceof JComboBox) { newValue = ((JComboBox) componen).getSelectedIndex();
            }else if (componen instanceof JCheckBox) { newValue = ((JCheckBox) componen).isSelected();
            }else if (componen instanceof JTextArea) { oldValue = ((JTextArea) componen).getText(); }
            if (!newValue.equals(oldValue)) { initButtonState(true); }
        }
    }
    
    private void initComponentsRules() {
        btnClose.registerKeyboardAction(btnClose.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);
 
        btnClose.registerKeyboardAction(btnClose.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);
        
        btnAdd.registerKeyboardAction(btnAdd.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);

        btnAdd.registerKeyboardAction(btnAdd.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);

        btnSave.registerKeyboardAction(btnSave.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);
 
        btnSave.registerKeyboardAction(btnSave.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);
        
        cmbPerform.setModel(ComponentUtils.getDefaultComboBoxModel(performList));
        
        TextComponentUtils.setNumericTextOnly(txtStokMax);
        TextComponentUtils.setNumericTextOnly(txtStokMin);
        TextComponentUtils.setNumericTextOnly(txtStokX);

        txtKode.addKeyListener(new ActionKeyListener());
        txtKode.addFocusListener(new ActionFocusGained());
        txtBar1.addKeyListener(new ActionKeyListener());
        txtBar1.addFocusListener(new ActionFocusGained());
        txtBar2.addKeyListener(new ActionKeyListener());
        txtBar2.addFocusListener(new ActionFocusGained());
        txtDept.addKeyListener(new ActionKeyListener());
        txtDept.addFocusListener(new ActionFocusGained());
        txtKemasan.addFocusListener(new ActionFocusGained());
        txtKemasan.addKeyListener(new ActionKeyListener());
        txtNama.addKeyListener(new ActionKeyListener());
        txtNama.addFocusListener(new ActionFocusGained());
        txtPrincipal.addFocusListener(new ActionFocusGained());
        txtPrincipal.addKeyListener(new ActionKeyListener());
        txtSatuan.addFocusListener(new ActionFocusGained());
        txtSatuan.addKeyListener(new ActionKeyListener());
        txtStokMax.addKeyListener(new ActionKeyListener());
        txtStokMax.addFocusListener(new ActionFocusGained());
        txtStokMin.addKeyListener(new ActionKeyListener());
        txtStokMin.addFocusListener(new ActionFocusGained());
        txtStokX.addKeyListener(new ActionKeyListener());
        txtStokX.addFocusListener(new ActionFocusGained());
        txtStruk.addKeyListener(new ActionKeyListener());
        txtStruk.addFocusListener(new ActionFocusGained());
        txtDiv.addKeyListener(new ActionKeyListener());
        txtDiv.addFocusListener(new ActionFocusGained());
        
        cmbPerform.addKeyListener(new ActionKeyListener());
        chkBKP.addKeyListener(new ActionKeyListener());
        chkConsi.addKeyListener(new ActionKeyListener());
        chkHalal.addKeyListener(new ActionKeyListener());
        cmbPerform.addFocusListener(new ActionFocusGained());
        chkBKP.addFocusListener(new ActionFocusGained());
        chkConsi.addFocusListener(new ActionFocusGained());
        chkHalal.addFocusListener(new ActionFocusGained());
    }      
    

}
